<?php

namespace app\admin\model;

use think\Model;

use think\Db;
use think\Request;
use think\Exception;//事务处理

class Journal extends Model
{
    //日记账登记
    public function getjournal($res)
    {
        $lang = $res['lang'];
        $moneyfive = $moneythree = $moneytwo = $moneyone = 0;
        $admin = session('admin');
        $dataaccounts = '';
        //不是管理员和CEO 记账科目显示(这个是根据是记账科目授权得到的)
        if ($admin['position_id'] != 1 && $admin['position_id'] != 2) {
            $accoundatas=array();
            //处理记账科目的显示
            $posid = $admin['position_id'];
            $whereacc[] = ["exp", "FIND_IN_SET($posid,position_ids)"];
            //授权的科目
            $accountdata = getables('fin_account', $whereacc, 'id,name,pid');
            $ids = array_column($accountdata, 'id');//授权的科目id
            //获取授权科目的父级
            $accid = array();
            foreach ($accountdata as $acckey => $accountval) {
                $accountdata[$acckey]['disable'] = 2;//能够选择
                $idsacc = getpostion('fin_account', $accountval['id']);//获取这个授权科目上级科目
                $chaacc = array_diff($idsacc, $ids);//两个数组之间的差集
                foreach ($chaacc as $chaacckey => $chaaccval) {
                    $accinfo = getinfo($chaaccval, 'fin_account', 'id,pid,name');
                    if (!in_array($accinfo['id'], $accid)) {
                        array_push($accid, $accinfo['id']);
                        $accinfo['disable'] = 1;//不能选择
                        $accoundatas[] = $accinfo;
                    }
                }
            }
            //记账科目的显示
            $dataaccounts = getTree(array_merge($accountdata, $accoundatas));
        }
        $dateday = getTimeDate(null, 7);
        $mapwhere['b.country_id'] = $res['country_id'];//国家选择
        //设置查看自己 还是子级 还是所有数据条件
        if ($admin['position_id'] != 1 && $admin['position_id'] != 2) {
            $country_poid = getValue('position', ['id' => $admin['position_id']], 'country_id');//登录者国家id
            //查看权限
            $admin_authids = explode(",", $admin['auth_ids']);//权限
            $posids = array_column(getFrames('position', null, $country_poid), 'id');
            $posidmap = implode(',', $posids);
            $mappostion['position_id'] = array('in', $posidmap);
            $adminids = array_column(Db::name('admin')->field('id')->where($mappostion)->select(), 'id');//获取能查看的员工的ids

            if (in_array('177', $admin_authids) && !in_array('178', $admin_authids)) {
                //查看自己下级的员工的日记账
                $mapwhere['a.create_id'] = ['in', $adminids];
                $maplast['admin_id']=['in', $adminids];//上月结余条件
                $lastyeat['admin_id']=['in', $adminids];//上年结余条件
            } elseif (in_array('176', $admin_authids) && !in_array('177', $admin_authids) && !in_array('178', $admin_authids)) {
                //只能看自己的账单
                $mapwhere['a.create_id'] = $admin['id'];
                $maplast['admin_id']=$admin['id'];//上月结余条件
                $lastyeat['admin_id']=$admin['id'];//上年结余条件
            } elseif(!in_array('176', $admin_authids) && !in_array('177', $admin_authids) && !in_array('178', $admin_authids)) {
                $mapwhere['a.create_id'] = $admin['id'];
                $maplast['admin_id']= $admin['id'];//上月结余条件
                $lastyeat['admin_id']=$admin['id'];//上年结余条件
            }
        }
        if (isset($res['journal']) && $res['journal'] == 'day') {
            //日记账
            $data = $this->alias('a')->join('nt_fin_account b', 'a.account_id=b.id', 'left')->field('a.*,b.name,b.adjust,b.pid')->where($mapwhere)->page($res['page'], $res['pageSize'])->order('a.happen_day desc')->select();

            $count = $this->alias('a')->join('nt_fin_account b', 'a.account_id=b.id', 'left')->where($mapwhere)->count();

        } elseif (isset($res['journal']) && $res['journal'] == 'month') {
            //月记账
            $years = $res['year'];
            $months = $res['month'];
            $yearsmonths = $years . '-' . $months;
            $yearmonth = getNextMonthDays($yearsmonths);
            $startime = strtotime($yearmonth[0]);//当月开始的时间戳
            $lasttime = strtotime($yearmonth[1]);//当月结束的时间戳
            $mapwhere['a.happen_day'] = ['between', "$startime,$lasttime"];
            //计算上月结余
            if ($months - 1 == 0) {
                //年份减1 月份就是12
                $maplast['year'] = $years - 1;
                $maplast['month'] = 12;
            } else {
                //当前年 月份减1
                $maplast['year'] = $years;
                $maplast['month'] = $months - 1;
            }
            //获取的是上期结余
            $moneyfive = Db::name('journal_month')->where($maplast)->sum('amount');
            $datares = $this->alias('a')->join('nt_fin_account b', 'a.account_id=b.id', 'left')->field('a.id,a.account_id,a.happen_day,sum(a.amount) as amount,b.name,b.adjust,b.pid')->where($mapwhere)->order('a.happen_day desc')->group('a.account_id')->select();

            $count = $this->alias('a')->join('nt_fin_account b', 'a.account_id=b.id', 'left')->where($mapwhere)->group('a.account_id')->count();
            //获取上级科目
            $accounpiddatas = $this->getpiddata($datares);
            //月账单数据
            $data = getTrees(array_merge($accounpiddatas, $datares));
        } elseif (isset($res['journal']) && $res['journal'] == 'year') {
            $startyear = $res['year'] . '-01-01';
            $lastyear = $res['year'] . '-12-31';
            $startime = strtotime($startyear);//当年开始的时间戳
            $lasttime = strtotime($lastyear);//当年结束的时间戳
            //年记账
            $mapwhere['a.happen_day'] = ['between', "$startime,$lasttime"];
            $lastyeat['year'] = $res['year'] - 1;
            //计算上一年的结余
            $moneyfive = Db::name('journal_year')->where($lastyeat)->sum('amount');

            $datares = $this->alias('a')->join('nt_fin_account b', 'a.account_id=b.id', 'left')->field('a.id,a.account_id,a.happen_day,sum(a.amount) as amount,b.name,b.adjust,b.pid')->where($mapwhere)->group('a.account_id')->order('a.happen_day desc')->select();
            //获取上级科目
            $accounpiddatas = $this->getpiddata($datares);
            //月账单数据
            $data = getTrees(array_merge($accounpiddatas, $datares));
            $count = $this->alias('a')->join('nt_fin_account b', 'a.account_id=b.id', 'left')->where($mapwhere)->group('a.account_id')->count();
        }
        $arr = array();
        //对数据进行总的处理
        foreach ($data as $datakey => $dataval) {
            //含有活动时间
            if (isset($dataval['happen_day']) && isset($dataval['update_at'])) {
                //日记账
                $data[$datakey]['update_date'] = getTimeDate($dataval['update_at'], 12);//更新时间
                //编辑者
                $data[$datakey]['updatename'] =getValue('admin',['id'=>$dataval['update_id']],'nickname');
                //发生日期
                $datehappen = $data[$datakey]['happen_date'] = getTimeDate($dataval['happen_day'], 15);
                if (in_array($datehappen, $arr)) {
                    $data[$datakey]['happen_date'] = '';
                }
                array_push($arr, $datehappen);
            }
            //科目名称
            $data[$datakey]['fin_accountname'] = $dataval['name'];
            //判断是否含有子级
            $infoacc_fu = Db::name('fin_account')->where('pid', $dataval['account_id'])->find();
            if ($infoacc_fu) {
                //含有子级，但是没有日记账
                $pid=Db::name('journal')->where('account_id',$infoacc_fu['id'])->find();
                if($pid){
                    $data[$datakey]['isexist'] = 1;
                }else{
                    $data[$datakey]['isexist'] = 2;
                }
            } else {
                $data[$datakey]['isexist'] = 2;
            }
            //处理颜色判断
            if ($dataval['adjust'] == 1) {
                //收入
                $data[$datakey]['color'] = 'blue';
                $data[$datakey]['code'] = '+';
                $moneyone += $dataval['amount'];
            } elseif ($dataval['adjust'] == 2) {
                //支出
                $data[$datakey]['color'] = 'red';
                $data[$datakey]['code'] = '-';
                $moneytwo += $dataval['amount'];
            } elseif ($dataval['adjust'] == 0) {
                //不调整
                $data[$datakey]['color'] = 'gray';
                $data[$datakey]['code'] = '';
                $moneythree += $dataval['amount'];
            }
            $data[$datakey]['time'] =time();
        }
        //页面结余
        $moneyfor = $moneyone - $moneytwo;//收入减支出
        $moneys = array(
            'onemoney' => $moneyone,//收入
            'twomoney' => $moneytwo,//支出
            'threemoney' => $moneythree,//不收不支出
            'formoney' => $moneyfor,//结余
            'fivemoney' => $moneyfive//上期结余
        );
        return array(
            'count' => $count,
            'data' => $data,
            'dateday' => $dateday,
            'moneys' => $moneys,
            'finaccounts' => $dataaccounts
        );
    }
    //日记账的添加与编辑
    public function journaladdedit($data)
    {
        $ckdata = notEmpty(['happen_day' => lang("date"), 'account_id' => lang("account_subject"), 'remarks' => lang("remark"), 'amount' => lang("amount")]);
        if ($ckdata['status']==2) {
            return $ckdata;
        }
        if ($data['amount'] <= 0) {
            return array('msg' => lang("the_amount_can't_be_negative"), 'status' => 0);
        }
        $act = $data['act'];
        unset($data['act']);
        $name = $data['remarks'] = trim($data['remarks']);
        $time = $data['happen_day'] = strtotime($data['happen_day']);
        $data['year'] = getTimeDate($time, 1);
        $data['month'] = getTimeDate($time, 2);
        if ($act == 'journaladd') {
            Db::startTrans();
            $data['create_at'] = $data['update_at'] = time();
            $admin_id = $data['create_id'] = $data['update_id'] = session('userid');
            $jounid = $this->strict(false)->insertGetId($data);//写入日记账表
            //更新这个用户的月账单和年账单
            $updateid = $this->updaemonthyear($admin_id);
            if ($jounid && $updateid) {
                Db::commit();
                return array('msg' => $name . lang("added_successfully"), 'status' => 1);
            } else {
                return array('msg' => $name . lang("add_failed"), 'status' => 0);
            }

        } elseif ($act == 'journaledit') {
            Db::startTrans();
            //更新日账单数据
            $data['update_at'] = time();
            $data['update_id'] = session('userid');
            $jounalid = $this->where('id', $data['id'])->update($data);
            $admin_id = $this->where('id', $data['id'])->value('create_id');
            $updateid = $this->updaemonthyear($admin_id);
            if ($jounalid !== false && $updateid) {
                Db::commit();
                return array('msg' => $name . lang("edited_successfully"), 'status' => 1);
            } else {
                return array('msg' => $name . lang("edit_failed"), 'status' => 0);
            }
        }
    }
    //日记删除
    public function journaldel($data)
    {
        $name = $data['name'];
        $admin_id = $this->where('id', $data['id'])->value('create_id');
        Db::startTrans();
        $retdelid = $this->where('id', $data['id'])->delete();//删除日记账表
        //判断该用户是否还存在数据
        $updateid = $this->updaemonthyear($admin_id);//更新月账单和年账单表
        if ($retdelid && $updateid) {
            Db::commit();
            return array('msg' => $name . lang("deleted_successfully"), 'status' => 1);
        } else {
            return array('msg' => $name . lang("failed_to_delete"), 'status' => 0);
        }
    }
    //月记账和年记账的重新写入
    protected function updaemonthyear($admin_id)
    {
        //删除这个用户之前的月账单和年账单
        Db::name('journal_month')->where('admin_id', $admin_id)->delete();
        Db::name('journal_year')->where('admin_id', $admin_id)->delete();
        //统计月账单
        $monthdata = Db::name('journal')->field('year,month')->where('create_id', $admin_id)->group('year,month')->select();
        foreach ($monthdata as $monthdatakey => $monthdataval) {
            $monthdata[$monthdatakey]['amount'] = $this->getmoney($monthdataval['year'], $monthdataval['month'], $admin_id);
            $monthdata[$monthdatakey]['admin_id'] = $admin_id;
        }
        //统计年账单
        $yeardata = Db::name('journal')->field('year')->where('create_id', $admin_id)->group('year')->select();
        foreach ($yeardata as $yeardatakey => $yeardataval) {
            $yeardata[$yeardatakey]['amount'] = $this->getmoney($yeardataval['year'], null, $admin_id);
            $yeardata[$yeardatakey]['admin_id'] = $admin_id;
        }
        //将数据写入年账单表和月账单表
        $monthid = Db::name('journal_month')->insertAll($monthdata);
        $yearid = Db::name('journal_year')->insertAll($yeardata);
        return 1;
    }
    protected function getmoney($year, $month, $admin_id)
    {
        $moneyjia = 0;
        $moneyjian = 0;
        $datares = Db::name('journal')->alias('a')->join('nt_fin_account b', 'a.account_id=b.id', 'left')->field('a.*,b.adjust')->where('a.create_id', $admin_id)->select();
        if ($month) {
            //统计月账单的金额
            foreach ($datares as $datareskey => $dataresval) {
                if ($dataresval['year'] == $year && $dataresval['month'] == $month) {
                    if ($dataresval['adjust'] == 1) {
                        //收入
                        $moneyjia += $dataresval['amount'];
                    } elseif ($dataresval['adjust'] == 2) {
                        //支出
                        $moneyjian += $dataresval['amount'];
                    }
                }
            }
        } else {
            //统计年账单的金额
            foreach ($datares as $datareskey => $dataresval) {
                if ($dataresval['year'] == $year) {
                    if ($dataresval['adjust'] == 1) {
                        //收入
                        $moneyjia += $dataresval['amount'];
                    } elseif ($dataresval['adjust'] == 2) {
                        //支出
                        $moneyjian += $dataresval['amount'];
                    }
                }
            }
        }
        //当月结余和年结余
        $moneys = $moneyjia - $moneyjian;
        return $moneys;
    }
    //获取账单的上级科目
    protected function getpiddata($datares)
    {
        $accoundatas = array();
        $ids = array_column($datares, 'account_id');
        $accid = array();
        foreach ($datares as $datareskey => $dataresval) {
            $pidsarr = getpostion('fin_account', $dataresval['account_id']);//获取上一级
            $changeacc = array_diff($pidsarr, $ids);
            foreach ($changeacc as $changeacckey => $changeaccval) {
                $accinfo =getinfo($changeaccval,'fin_account','id as account_id,pid,name');
                $accinfo['happen_day'] = $accinfo['adjust'] = $accinfo['id'] = '';
                $accinfo['amount'] = 0;
                if (!in_array($accinfo['account_id'], $accid)) {
                    array_push($accid, $accinfo['account_id']);
                    $accoundatas[] = $accinfo;
                }
            }
        }
        return $accoundatas;
    }
}